package com.ts.file;

import com.ts.comm.SysString;
import net.lingala.zip4j.core.ZipFile;
import net.lingala.zip4j.model.FileHeader;
import net.lingala.zip4j.model.ZipParameters;
import net.lingala.zip4j.util.Zip4jConstants;

import java.io.File;
import java.util.List;

/**
 * 压缩文件处理工具类
 * Created by xhc on 2017-3-23.
 */
public class SysZip {

    /**
     * 解压缩文件
     * @param souFile 压缩文件地址
     * @param desDir 解压到哪个目录
     * @param pwd 压缩文件密码
     * @throws Exception
     */
    public static void unZip(String souFile, String desDir, String pwd)
            throws Exception {
        ZipFile zipFile = new ZipFile(souFile);
        zipFile.setFileNameCharset("GBK");
        if (!zipFile.isValidZipFile()) {
            throw new Exception("压缩文件不合法,可能被损坏.");
        }
        if (zipFile.isEncrypted()) {
            zipFile.setPassword(pwd);
        }
        File destDir = new File(desDir);     // 解压目录
        if (!destDir.exists()) {
            destDir.mkdir();
        }
        zipFile.extractAll(desDir);
    }

    /**
     * 压缩文件
     * @param desZip 生成的zip文件路径 f:/a.zip
     * @param souDir 要压缩文件目录 f:/a
     * @param pwd 加密密码
     * @throws Exception
     */
    public static void zip(String desZip,String souDir,String pwd)
            throws Exception {
        File fl=new File(souDir);
        if(!fl.exists())
        {
            throw new Exception("文件不存在！");
        }
        ZipFile zipFile = new ZipFile(desZip);
        zipFile.setFileNameCharset("GBK");
        ZipParameters parameters = new ZipParameters();
        parameters.setCompressionMethod(Zip4jConstants.COMP_DEFLATE);// 压缩方式

        parameters.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_NORMAL);// 压缩级别

        if(!SysString.isEmpty(pwd))
        {
            parameters.setEncryptFiles(true);

            parameters.setEncryptionMethod(Zip4jConstants.ENC_METHOD_AES);// 加密方式

            parameters.setAesKeyStrength(Zip4jConstants.AES_STRENGTH_256);

            parameters.setPassword(pwd);
        }else
        {
            parameters.setEncryptFiles(false);
        }

        parameters.setIncludeRootFolder(false);//是否显示根文件夹
        zipFile.addFolder(souDir,parameters);
    }

    /**
     * 移除压缩文件中的文件或目录
     * @param sPath zip文件路径
     * @param removeFileName 要移除的文件或文件夹
     * @throws Exception
     */
    public static  void removeZipFile(String sPath,String removeFileName)throws Exception{
        ZipFile zipFile = new ZipFile(sPath);
        zipFile.setFileNameCharset("GBK");
        File f=new File(removeFileName);
        //判断是否是目录，是目录删除子文件
        if(f.isDirectory()) {
            // 遍历压缩文件中所有的FileHeader, 将指定删除目录下的子文件删除
            List allHeaders = zipFile.getFileHeaders();
            FileHeader fileHeader = zipFile.getFileHeader(sPath);
            for (int i = 0, len = allHeaders.size(); i < len; i++) {
                FileHeader subHeader = (FileHeader) allHeaders.get(i);
                zipFile.removeFile(subHeader);
            }
            // 最后删除指定目录
            zipFile.removeFile(fileHeader);
        }else{
            zipFile.removeFile(removeFileName);
        }
    }
}
